package com.ctshk.rpc.season.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.Currency;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.DateUtil;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.season.dto.*;
import com.ctshk.rpc.season.entity.SeasonFixedDepartDate;
import com.ctshk.rpc.season.entity.SeasonFixedProduct;
import com.ctshk.rpc.season.entity.SeasonFixedProductPackage;
import com.ctshk.rpc.season.mapper.SeasonFixedDepartDateMapper;
import com.ctshk.rpc.season.mapper.SeasonFixedProductMapper;
import com.ctshk.rpc.season.mapper.SeasonFixedProductPackageMapper;
import com.ctshk.rpc.season.req.*;
import com.ctshk.rpc.season.service.*;
import com.ctshk.rpc.user.req.UserFootPointReq;
import com.ctshk.rpc.user.service.IUserFootPointService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * <p>
 * 套票-固定套票单项产品打包表 服务实现类
 * </p>
 *
 * @author 杨林
 * @since 2021-03-09
 */
@DubboService
public class SeasonFixedProductPackageServiceImpl extends ServiceImpl<SeasonFixedProductPackageMapper, SeasonFixedProductPackage> implements ISeasonFixedProductPackageService {

    @Autowired
    private SeasonFixedProductMapper seasonFixedProductMapper;
    @Autowired
    private SeasonFixedProductPackageMapper seasonFixedProductPackageMapper;
    @Autowired
    private ISeasonFixedProductPackageBusService seasonFixedProductPackageBusService;
    @Autowired
    private ISeasonFixedProductPackageAirService seasonFixedProductPackageAirService;
    @Autowired
    private ISeasonFixedProductPackageHotelService seasonFixedProductPackageHotelService;
    @Autowired
    private ISeasonFixedProductPackageShipService seasonFixedProductPackageShipService;
    @Autowired
    private ISeasonFixedProductPackageTrainService seasonFixedProductPackageTrainService;
    @Autowired
    private ISeasonFixedProductPackageScenicService seasonFixedProductPackageScenicService;
    @Autowired
    private SeasonFixedDepartDateMapper seasonFixedDepartDateMapper;
    @Autowired
    private ISeasonFixedProductPackageLocalFunService seasonFixedProductPackageLocalFunService;
    @Autowired
    private ISeasonFixedProductPackageCommodityService seasonFixedProductPackageCommodityService;
    @Autowired
    private ISeasonFixedProductService seasonFixedProductService;
    @Autowired
    private ISeasonProductStrategyService seasonProductStrategyService;
    @DubboReference
    private IUserFootPointService userFootPointService;

    /* @MethodName: 固定套票 产品设置
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/9 11:31
     **/
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Result setFixedSeasonProduct(TokenUser user, SeasonFixedSetReq req) {
        if (user == null) {
            return Result.failed(SystemError.USER_1000);
        }
        //获取固定套票信息 如果没有直接返回错误
        SeasonFixedProduct seasonFixedProduct = seasonFixedProductMapper.selectById(req.getProductId());
        if (seasonFixedProduct == null) {
            return Result.failed(SystemError.SEASON_TICKET_20004);
        }
        LocalDateTime now = LocalDateTime.now();
        SeasonFixedProductPackage seasonFixedProductPackage = new SeasonFixedProductPackage();
        seasonFixedProductPackage.setPackageProductFlag(req.getPackageProductFlag());
        seasonFixedProductPackage.setBackTerms(req.getBackTerms());
        seasonFixedProductPackage.setSeasonTypeId(req.getSeasonTypeId());
        seasonFixedProductPackage.setSeasonTypeName(req.getSeasonTypeName());
        seasonFixedProductPackage.setTravelBrochureFile(req.getTravelBrochureFile());

        seasonFixedProductPackage.setProductId(seasonFixedProduct.getId());//打包设置产品id
        seasonFixedProductPackage.setCreateId(user.getId());//创建id
        seasonFixedProductPackage.setGmtCreate(now);//创建时间
        seasonFixedProductPackage.setGmtModified(now);//修改时间
        seasonFixedProductPackage.setIsDeleted(IsDeletedCode.NO.getCode());//删除标识
        Long packageId = IdWorker.getId();//生成id
        seasonFixedProductPackage.setId(packageId);
        seasonFixedProductPackageMapper.insert(seasonFixedProductPackage);
        seasonFixedProduct.setSeasonTypeId(req.getSeasonTypeId().toString());
        seasonFixedProduct.setSeasonTypeName(req.getSeasonTypeName());
        seasonFixedProductMapper.updateById(seasonFixedProduct);
        //批量处理套票相关产品信息
        batchUpdateProductInfo(user, req, false, packageId);
        return Result.success(seasonFixedProductPackage);
    }

    /* @MethodName: 编辑固定套票时候 批量处理 套票 相关产品信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/12 16:05
     **/
    @Override
    @Transactional(rollbackFor = BusinessException.class)
    public void batchUpdateProductInfo(TokenUser user, SeasonFixedSetReq req, boolean flag, Long packageId) {
        List<SeasonFixedProductPackageBusReq> busReqList = req.getSeasonFixedProductPackageBusList();
        //不为空的时候 保存 巴士信息
        if (null != busReqList && busReqList.size() > 0) {
            if (flag) {//先将原来的清空
                seasonFixedProductMapper.deleteBusByPackageId(packageId);
            }
            seasonFixedProductPackageBusService.batchBusProduct(user.getId(), packageId, busReqList);
        }
        List<SeasonFixedProductPackageAirReq> airReqList = req.getSeasonFixedProductPackageAirList();
        //机票产品集合 不为空的时候 保存 机票信息
        if (null != airReqList && airReqList.size() > 0) {
            if (flag) {//先将原来的清空
                seasonFixedProductPackageAirService.deletePreviousAir(user.getId(), packageId);
            }
            seasonFixedProductPackageAirService.batchAirProduct(user.getId(), packageId, airReqList);
        }


        List<SeasonFixedProductPackageHotelReq> hotelReqList = req.getSeasonFixedProductPackageHotelList();
        //酒店产品集合 不为空的时候 保存 酒店信息
        if (null != hotelReqList && hotelReqList.size() > 0) {
            if (flag) {//先将原来的清空
                seasonFixedProductPackageHotelService.deletePreviousHotel(user.getId(), packageId);
            }
            seasonFixedProductPackageHotelService.batchHotelProduct(user.getId(), packageId, hotelReqList);
        }


        List<SeasonFixedProductPackageScenicReq> scenicReqList = req.getSeasonFixedProductPackageScenicList();
        //景点门票产品集合 不为空的时候 保存 景点门票信息
        if (null != scenicReqList && scenicReqList.size() > 0) {
            //先将原来的酒店门票产品信息清空
            if (flag) {//先将原来的清空
                seasonFixedProductPackageScenicService.deletePreviousScenic(user.getId(), packageId);
            }
            seasonFixedProductPackageScenicService.batchScenicProduct(user.getId(), packageId, scenicReqList);
        }

        List<SeasonFixedProductPackageShipReq> shipReqList = req.getSeasonFixedProductPackageShipList();
        //船票产品集合 不为空的时候 保存 船票信息
        if (null != shipReqList && shipReqList.size() > 0) {
            if (flag) {//先将原来的清空
                seasonFixedProductPackageShipService.deletePreviousShip(user.getId(), packageId);
            }
            seasonFixedProductPackageShipService.batchShipProduct(user.getId(), packageId, shipReqList);
        }


        List<SeasonFixedProductPackageTrainReq> trainReqList = req.getSeasonFixedProductPackageTrainList();
        //火车票产品集合 不为空的时候 保存 火车票信息
        if (null != trainReqList && trainReqList.size() > 0) {
            if (flag) { //先将原来的火车票产品信息清空
                seasonFixedProductPackageTrainService.deletePreviousTrain(user.getId(), packageId);
            }
            seasonFixedProductPackageTrainService.batchTrainProduct(user.getId(), packageId, trainReqList);
        }
        List<SeasonFixedProductPackageLocalFunReq> localFunList = req.getSeasonFixedProductPackageLocalFunReqList();
        //当地玩乐集合 不为空的时候 保存 当地玩乐信息
        if (null != localFunList && localFunList.size() > 0) {
            if (flag) {
                seasonFixedProductMapper.deleteLocalFunByPackageId(packageId);
            }
            seasonFixedProductPackageLocalFunService.batchLocalFunProduct(user.getId(), packageId, localFunList);
        }
        List<SeasonFixedProductPackageCommodityReq> commodityList = req.getSeasonFixedProductPackageCommodityReqList();
        //当地商品集合 不为空的时候 保存 商品信息
        if (null != commodityList && commodityList.size() > 0) {
            if (flag) {
                seasonFixedProductMapper.deleteCommodityByPackageId(packageId);
            }
            seasonFixedProductPackageCommodityService.batchCommodityProduct(user.getId(), packageId, commodityList);
        }
        //出发日期
        if (null != req.getDepartDateList() && req.getDepartDateList().size() > 0) {
            if (flag) {
                seasonFixedProductMapper.deleteDepartDateByPackageId(packageId);
            }
            List<SeasonFixedDepartDate> departDateList = new LinkedList<>();
            for (LocalDate date : req.getDepartDateList()) {
                SeasonFixedDepartDate departDate = new SeasonFixedDepartDate();
                departDate.setCreateId(user.getId());
                departDate.setGmtCreate(LocalDateTime.now());
                departDate.setDepartDate(date);
                departDate.setPackageId(packageId);
                departDate.setProductId(req.getProductId());//设置产品id
                departDate.setId(SnowflakeIdWorker.nextId());
                departDate.setIsDeleted(IsDeletedCode.NO.getCode());
                departDateList.add(departDate);
            }
            seasonFixedDepartDateMapper.insertBatchSomeColumn(departDateList);
        }
        if (SeasonType.VALID.getKey().equals(req.getOperationType())) {
            seasonFixedProductService.updateFixedSeasonProductState(user, new SeasonFixedProductStateReq(SeasonType.VALID.getKey(), req.getProductId().toString()));
        }
    }

    @Override
    public void getProductSetInfo(FixedSeasonDetailsDTO fixedSeasonProductInfoDTO) {
        Long packageId = fixedSeasonProductInfoDTO.getPackageId();
        String packageProductFlag = fixedSeasonProductInfoDTO.getPackageProductFlag();

        String[] flagList = packageProductFlag.split(",");
        for (String flag : flagList) {
            SeasonIndividualType productFlagEnum = SeasonIndividualType.getEnumType(flag);
            switch (productFlagEnum) {
                //机票
                case AIR:
                    // 固定套票飞机票产品信息
                    List<SeasonFixedProductPackageAirDTO> seasonFixedProductPackageAirList = seasonFixedProductPackageAirService.getSeasonFixedProductAirDtoList(packageId);
                    fixedSeasonProductInfoDTO.setSeasonFixedProductPackageAirList(seasonFixedProductPackageAirList);
                    break;
                //酒店
                case HOTEL:
                    //固定套票 酒店产品信息
                    List<SeasonFixedProductPackageHotelDTO> seasonFixedProductPackageHoteList = seasonFixedProductPackageHotelService.getSeasonFixedProductHotelDtoList(packageId);
                    fixedSeasonProductInfoDTO.setSeasonFixedProductPackageHoteList(seasonFixedProductPackageHoteList);
                    break;
                //巴士
                case BUS:
                    //固定套票 巴士票产品信息
                    List<SeasonFixedProductPackageBusDTO> seasonFixedProductPackageBusList = seasonFixedProductPackageBusService.getSeasonFixedProductBusDtoList(packageId);
                    fixedSeasonProductInfoDTO.setSeasonFixedProductPackageBusList(seasonFixedProductPackageBusList);
                    break;
                //船票
                case SHIP:
                    //固定套票船票产品信息
                    List<SeasonFixedProductPackageShipDTO> seasonFixedProductPackageShipList = seasonFixedProductPackageShipService.getSeasonFixedProductShipDtoList(packageId);
                    fixedSeasonProductInfoDTO.setSeasonFixedProductPackageShipList(seasonFixedProductPackageShipList);
                    break;
                //火车
                case TRAIN:
                    //固定套票 火车票产品信息
                    List<SeasonFixedProductPackageTrainDTO> seasonFixedProductPackageTrainList = seasonFixedProductPackageTrainService.getSeasonFixedProductTrainDtoList(packageId);
                    fixedSeasonProductInfoDTO.setSeasonFixedProductPackageTrainList(seasonFixedProductPackageTrainList);
                    break;

                //景点门票
                case SCENIC:
                    //固定套票 景点门票产品信息
                    List<SeasonFixedProductPackageScenicDTO> seasonFixedProductPackageScenicList = seasonFixedProductPackageScenicService.getSeasonFixedProductScenicDtoList(packageId);
                    fixedSeasonProductInfoDTO.setSeasonFixedProductPackageScenicList(seasonFixedProductPackageScenicList);
                    break;
                //当地玩乐
                case LOCALFUN:
                    //固定套票 景点门票产品信息
                    List<SeasonFixedProductPackageLocalFunDTO> seasonFixedProductPackageLocalFunDTOList = seasonFixedProductPackageLocalFunService.getSeasonFixedProductLocalFunDtoList(packageId);
                    fixedSeasonProductInfoDTO.setSeasonFixedProductPackageLocalFunList(seasonFixedProductPackageLocalFunDTOList);
                    break;
                //当地玩乐
                case COMMODITY:
                    //固定套票 商品产品信息
                    List<SeasonFixedProductPackageCommodityDTO> seasonFixedProductPackageCommodityDTOList = seasonFixedProductPackageCommodityService.getSeasonFixedProductCommodityDtoList(packageId);
                    fixedSeasonProductInfoDTO.setSeasonFixedProductPackageCommodityList(seasonFixedProductPackageCommodityDTOList);
                    break;
            }
        }
    }


    /* @MethodName: 获取固定套票打包产品信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/22 9:22
     **/
    @Override
    public void getPackageProduct(FixedSeasonDetailsDTO dto, LocalDate startDate, Integer travelDays, Integer travelNights, Integer channelType,Long channelId) {
        String seasonPackageProductFlag = dto.getPackageProductFlag();
        if (seasonPackageProductFlag.contains(",")) {
            String str[] = seasonPackageProductFlag.split(",");
            for (String productFlag : str) {
                getSinglePriceList(null, productFlag, dto, startDate, travelDays, travelNights, channelType,channelId);
            }
        } else {
            getSinglePriceList(null, seasonPackageProductFlag, dto, startDate, travelDays, travelNights, channelType,channelId);
        }
    }


    @Override
    public BigDecimal getPackageDefaultProduct(FixedSeasonDetailsDTO dto, LocalDate startDate, Integer travelDays, Integer travelNights, Integer channelType,Long userId) {
        BigDecimal price = BigDecimal.ZERO;
        String str[] = dto.getPackageProductFlag().split(",");
        for (String productFlag : str) {
            SeasonIndividualType seasonTypeEnum = SeasonIndividualType.getEnumType(productFlag);
            switch (seasonTypeEnum) {
                //机票
                case AIR:
                    // 固定套票飞机票产品信息
                    List<SeasonFixedProductPackageAirDTO> seasonFixedProductPackageAirList = seasonFixedProductPackageAirService.getDefaultAirData(dto.getPackageId(), startDate, DateUtil.getNextNDay(startDate, travelDays), userId, channelType);
                    dto.setSeasonFixedProductPackageAirList(seasonFixedProductPackageAirList);

                    for(SeasonFixedProductPackageAirDTO seasonFixedProductPackageAirDTO : seasonFixedProductPackageAirList){
                        price = price.add(seasonFixedProductPackageAirDTO.getCost());
                    }
                    break;
                //酒店
                case HOTEL:
                    List<SeasonFixedProductPackageHotelDTO> seasonFixedProductPackageHoteList = seasonFixedProductPackageHotelService.getDefaultHotelData(dto.getPackageId(), startDate, DateUtil.getNextNDay(startDate, travelNights), userId, channelType);
                    dto.setSeasonFixedProductPackageHoteList(seasonFixedProductPackageHoteList);

                    for(SeasonFixedProductPackageHotelDTO seasonFixedProductPackageHotelDTO : seasonFixedProductPackageHoteList){
                        price = price.add(seasonFixedProductPackageHotelDTO.getCost());
                    }

                    break;
                //巴士
                case BUS:
                    List<SeasonFixedProductPackageBusDTO> seasonFixedProductPackageBusList = seasonFixedProductPackageBusService.getBusByPackageId(dto.getPackageId(), startDate, DateUtil.getNextNDay(startDate, travelDays), userId, channelType);
                    dto.setSeasonFixedProductPackageBusList(seasonFixedProductPackageBusList);
                    break;
                //船票
                case SHIP:
                    //固定套票船票产品信息
                    List<SeasonFixedProductPackageShipDTO> seasonFixedProductPackageShipList = seasonFixedProductPackageShipService.getShipByPackageId(dto.getPackageId(), startDate, DateUtil.getNextNDay(startDate, travelDays), userId, channelType);
                    dto.setSeasonFixedProductPackageShipList(seasonFixedProductPackageShipList);
                    break;
                //酒店+火车
                case TRAIN:
                    //固定套票 火车票产品信息
                    List<SeasonFixedProductPackageTrainDTO> seasonFixedProductPackageTrainList = seasonFixedProductPackageTrainService.getTrainByPackageId(dto.getPackageId(), startDate, DateUtil.getNextNDay(startDate, travelDays), userId, channelType);
                    dto.setSeasonFixedProductPackageTrainList(seasonFixedProductPackageTrainList);
                    break;

                //景点门票
                case SCENIC:
                    //固定套票 火车票产品信息
                    List<SeasonFixedProductPackageScenicDTO> seasonFixedProductPackageScenicList = seasonFixedProductPackageScenicService.getDefaultScenicData(dto.getPackageId(), startDate, userId, channelType);
                    dto.setSeasonFixedProductPackageScenicList(seasonFixedProductPackageScenicList);

                    for(SeasonFixedProductPackageScenicDTO seasonFixedProductPackageScenicDTO : seasonFixedProductPackageScenicList){
                        price = price.add(seasonFixedProductPackageScenicDTO.getCost());
                    }
                    break;

                //当地玩乐
                case LOCALFUN:
                    //固定套票 火车票产品信息
                    List<SeasonFixedProductPackageLocalFunDTO> seasonFixedProductPackageLocalFunList = seasonFixedProductPackageLocalFunService.getDefaultLocalFunData(dto.getPackageId(), startDate, userId, channelType);
                    dto.setSeasonFixedProductPackageLocalFunList(seasonFixedProductPackageLocalFunList);
//
                    for(SeasonFixedProductPackageLocalFunDTO seasonFixedProductPackageLocalFunDTO : seasonFixedProductPackageLocalFunList){
                        price = price.add(seasonFixedProductPackageLocalFunDTO.getCost());
                    }

                    break;
                //商品
                case COMMODITY:
                    //固定套票 火车票产品信息
                    List<SeasonFixedProductPackageCommodityDTO> seasonFixedProductPackageCommodityList = seasonFixedProductPackageCommodityService.getDefaultCommodityData(dto.getPackageId(), startDate, userId, channelType);
//                    seasonFixedProductPackageCommodityList.forEach(item -> {
//                        price.add(item.getCost());
//                    });

                    for(SeasonFixedProductPackageCommodityDTO seasonFixedProductPackageCommodityDTO : seasonFixedProductPackageCommodityList){
                        price = price.add(seasonFixedProductPackageCommodityDTO.getCost());
                    }

                    dto.setSeasonFixedProductPackageCommodityList(seasonFixedProductPackageCommodityList);
                    break;
            }
        }
        return price;
    }

    private void getSinglePriceList(String tripType, String productFlag, FixedSeasonDetailsDTO dto, LocalDate startDate, Integer travelDays, Integer travelNights, Integer channelType,Long channelId) {
        //固定套票酒店产品信息
        SeasonIndividualType seasonTypeEnum = SeasonIndividualType.getEnumType(productFlag);
        switch (seasonTypeEnum) {
            //机票
            case AIR:
                // 固定套票飞机票产品信息
                List<SeasonFixedProductPackageAirDTO> seasonFixedProductPackageAirList = seasonFixedProductPackageAirService.getAirByPackageId(tripType, dto.getPackageId(), startDate, DateUtil.getNextNDay(startDate, travelDays), channelId, channelType);
                dto.setSeasonFixedProductPackageAirList(seasonFixedProductPackageAirList);
                break;
            //酒店
            case HOTEL:
                List<SeasonFixedProductPackageHotelDTO> seasonFixedProductPackageHoteList = seasonFixedProductPackageHotelService.getHotelByPackageId(dto.getPackageId(), startDate, DateUtil.getNextNDay(startDate, travelNights), channelId, channelType);
                dto.setSeasonFixedProductPackageHoteList(seasonFixedProductPackageHoteList);
                break;
            //巴士
            case BUS:
                List<SeasonFixedProductPackageBusDTO> seasonFixedProductPackageBusList = seasonFixedProductPackageBusService.getBusByPackageId(dto.getPackageId(), startDate, DateUtil.getNextNDay(startDate, travelDays), channelId, channelType);
                dto.setSeasonFixedProductPackageBusList(seasonFixedProductPackageBusList);
                break;
            //船票
            case SHIP:
                //固定套票船票产品信息
                List<SeasonFixedProductPackageShipDTO> seasonFixedProductPackageShipList = seasonFixedProductPackageShipService.getShipByPackageId(dto.getPackageId(), startDate, DateUtil.getNextNDay(startDate, travelDays), channelId, channelType);
                dto.setSeasonFixedProductPackageShipList(seasonFixedProductPackageShipList);
                break;
            //酒店+火车
            case TRAIN:
                //固定套票 火车票产品信息
                List<SeasonFixedProductPackageTrainDTO> seasonFixedProductPackageTrainList = seasonFixedProductPackageTrainService.getTrainByPackageId(dto.getPackageId(), startDate, DateUtil.getNextNDay(startDate, travelDays), channelId, channelType);
                dto.setSeasonFixedProductPackageTrainList(seasonFixedProductPackageTrainList);
                break;

            //景点门票
            case SCENIC:
                //固定套票 火车票产品信息
                List<SeasonFixedProductPackageScenicDTO> seasonFixedProductPackageScenicList = seasonFixedProductPackageScenicService.getScenicByPackageId(dto.getPackageId(), startDate, channelId, channelType);
                dto.setSeasonFixedProductPackageScenicList(seasonFixedProductPackageScenicList);
                break;

            //当地玩乐
            case LOCALFUN:
                //固定套票 火车票产品信息
                List<SeasonFixedProductPackageLocalFunDTO> seasonFixedProductPackageLocalFunList = seasonFixedProductPackageLocalFunService.getLocalFunByPackageId(dto.getPackageId(), startDate, channelId, channelType);
                dto.setSeasonFixedProductPackageLocalFunList(seasonFixedProductPackageLocalFunList);
                break;
            //商品
            case COMMODITY:
                //固定套票 火车票产品信息
                List<SeasonFixedProductPackageCommodityDTO> seasonFixedProductPackageCommodityList = seasonFixedProductPackageCommodityService.getCommodityByPackageId(dto.getPackageId(), startDate, channelId, channelType);
                dto.setSeasonFixedProductPackageCommodityList(seasonFixedProductPackageCommodityList);
                break;
        }
    }

    /* @MethodName: 预订中心-固定套票 搜索列表  默认显示推荐套票
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/18 9:23
     **/
    @Override
    public PageResponse<FixedSeasonProductPageDTO> searchReserveCenterSeasonFixed(SearchFixedProductReq req, TokenUser user) {
        IPage<FixedSeasonProductPageDTO> page = new Page<>(req.getPageNo(), req.getPageSize());
        //搜索固定套票列表
        req.setSellStatus(SeasonType.VALID.getCode());
        req.setApprovalStatus(SeasonType.REVIEW_PASS.getCode());
        req.setOnShelfStatus(SeasonType.IS_ONSHELF.getCode());
        req.setChannelId(SeasonType.OFFLINE_SELF_CHANNEL_TYPE.getCode());
        if (!req.isSearch()) {
            req.setIsRecommend(SeasonType.IS_RECOMMEND.getCode());
        }
        if (StringUtils.isBlank(req.getStartDate())) {
            req.setStartDate(DateUtil.format(new Date(), DateUtil.fmt_day));
        }
        page = seasonFixedProductMapper.searchSeasonFixedProduct(req, page);
        List<FixedSeasonProductPageDTO> seasonProductList = page.getRecords();
        Iterator<FixedSeasonProductPageDTO> it = seasonProductList.iterator();
        while (it.hasNext()) {
            FixedSeasonProductPageDTO dto = it.next();
            LocalDate startDate = DateUtil.parse(req.getStartDate(), DateUtil.fmt_day);
            PackageProductCostDTO costDTO = seasonFixedProductService.getPackageProduct(dto.getPackageProductFlag(), dto.getPackageId(), startDate, dto.getTravelDays(), dto.getTravelNights(), dto.getChargeUserId(), SeasonType.OFFLINE_SELF_CHANNEL_TYPE.getCode());
            if (!costDTO.getIsShow()) {//当没有查到其中一个打包产品的成本价 时候 就不显示
                it.remove();
            } else {
                //获取固定套票加幅值 以当前登录的用户Id
                BigDecimal fixedSeasonCostPrice = getFixedSeasonAdjust(costDTO.getCostPrice(), user.getId(), startDate, dto.getProductId(), SeasonType.OFFLINE_SELF_CHANNEL_TYPE.getCode());
                dto.setProductPrice(fixedSeasonCostPrice);
            }
        }
        PageResponse<FixedSeasonProductPageDTO> result = new PageResponse<>(page.getRecords(), page.getCurrent() == 1,
                page.getTotal() <= (page.getCurrent() * page.getSize()),
                page.getTotal(), page.getCurrent(), page.getSize());
        return result;
    }


    /* @MethodName: 获取固定套票的加幅值
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/18 18:00
     **/
    public BigDecimal getFixedSeasonAdjust(BigDecimal cost, Long useId, LocalDate date, Long productId, Integer channelType) {
        //根据套票产品成本价 固定套票加幅值
        BigDecimal adjustValue = seasonProductStrategyService.getFixedSeasonAdjustValueByCost(useId, date, productId, cost, channelType);
        return adjustValue;
    }

    /* @MethodName: 预订中心获取固定套票详情
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/20 14:45
     **/
    @Override
    public Result getFixedSeasonProductDetails(Long productId, Long userId, Integer channelType,Long channelId) {
        Result result = seasonFixedProductService.getFixedSeasonProductDetails(productId);
        if (result.isSuccess()) {
            //固定套票各种产品设置
            FixedSeasonDetailsDTO detailsDTO = (FixedSeasonDetailsDTO) result.getData();
            LocalDate startDate = LocalDate.now();
            //添加各个单项的值
            LocalDate endDate = startDate.plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
            List<DepartCalendarDTO> departCalendarDTOList = seasonFixedProductService.getDepartCalendarDTOList(productId, startDate, endDate, detailsDTO, channelType, userId);
            detailsDTO.setDepartCalendarDTOList(departCalendarDTOList);
            if (null != departCalendarDTOList && departCalendarDTOList.size() > 0) {
                List<LocalDate> localDate = departCalendarDTOList.get(0).getValidDateList();
                BigDecimal fixedSeasonCostPrice = BigDecimal.ZERO;
                if (null != localDate && localDate.size() > 0) {
                    LocalDate departDate = localDate.get(0);
                    //获取固定套票 打包产品的 价格
                    getPackageProduct(detailsDTO, departDate, detailsDTO.getTravelDays(), detailsDTO.getTravelNights(), channelType,channelId);
                    BigDecimal cost = getFixedSeasonProductCosts(detailsDTO);
                    //获取固定套票加幅值
                    fixedSeasonCostPrice = getFixedSeasonAdjust(cost, userId, departDate, productId, channelType);
                }
                detailsDTO.setProductPrice(fixedSeasonCostPrice);
            }
            return Result.success(detailsDTO);
        } else {
            return result;
        }
    }

    /* @MethodName: App预订中心获取固定套票详情
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/20 14:45
     **/
    @Override
    public Result getAppFixedSeasonProductDetails(AppSearchFixedProductReq req, Long userId) {
        Long productId = req.getSeasonTypeId();
        Integer channelType = SeasonType.ONLINE_SELF_CHANNEL_TYPE.getCode();
        Result result = seasonFixedProductService.getFixedSeasonProductDetails(productId);
        if (result.isSuccess()) {
            //固定套票各种产品设置
            FixedSeasonDetailsDTO detailsDTO = (FixedSeasonDetailsDTO) result.getData();

            LocalDate startDate = LocalDate.now();
            //添加各个单项的值
            LocalDate endDate = startDate.plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());

            List<DepartCalendarDTO> departCalendarDTOList = seasonFixedProductService.getDepartCalendarDTOList(productId
                    , startDate, endDate, detailsDTO, channelType, req.getChannelId());

            detailsDTO.setDepartCalendarDTOList(departCalendarDTOList);
            if (null != departCalendarDTOList && departCalendarDTOList.size() > 0) {
                List<LocalDate> localDate = departCalendarDTOList.get(0).getValidDateList();
                BigDecimal fixedSeasonCostPrice = BigDecimal.ZERO;
                if (null != localDate && localDate.size() > 0) {
                    LocalDate departDate = localDate.get(0);
                    //获取固定套票 打包产品的 价格
                    BigDecimal cost = getPackageDefaultProduct(detailsDTO
                            , departDate, detailsDTO.getTravelDays(), detailsDTO.getTravelNights()
                            , SeasonType.OFFLINE_SELF_CHANNEL_TYPE.getCode(),detailsDTO.getChargeUserId());
                    //BigDecimal cost = getFixedSeasonProductCosts(detailsDTO);
                    //获取固定套票加幅值
                    fixedSeasonCostPrice = getFixedSeasonAdjust(cost, req.getChannelId()
                            , departDate, productId, channelType);
                }
                detailsDTO.setProductPrice(fixedSeasonCostPrice);
            }
            List<IntroducePictureDTO> introducePictures = JSONArray.parseArray(detailsDTO.getIntroducePicture(), IntroducePictureDTO.class);
            if (null != introducePictures && introducePictures.size() > 0) {
                List<String> strList = new ArrayList<>();
                introducePictures.forEach(item -> {
                    strList.add(item.getUrl());
                });
                detailsDTO.setIntroducePictures(strList);
                detailsDTO.setIntroducePicture(null);
            }
            List<IntroducePictureDTO> features = JSONArray.parseArray(detailsDTO.getFeature(), IntroducePictureDTO.class);
            if (null != features && features.size() > 0) {
                List<String> strList = new ArrayList<>();
                features.forEach(item -> {
                    strList.add(item.getValue());
                });
                detailsDTO.setFeatures(strList);
                detailsDTO.setFeature(null);
            }
            List<IntroducePictureDTO> introduceVideos = JSONArray.parseArray(detailsDTO.getIntroduceVideo(), IntroducePictureDTO.class);
            if (null != introduceVideos && introduceVideos.size() > 0) {
                List<String> strList = new ArrayList<>();
                introduceVideos.forEach(item -> {
                    strList.add(item.getUrl());
                });
                detailsDTO.setIntroduceVideos(strList);
                detailsDTO.setIntroduceVideo(null);
            }
            // 增加用户足迹
            addUserFootPoint(detailsDTO, productId, userId);
            return Result.success(detailsDTO);
        } else {
            return result;
        }
    }

    @Override
    public Result getChangeAppFixedSeasonProductDetails(AppSearchFixedProductReq req, Long userId,Long channelId) {
        Long productId = req.getSeasonTypeId();
        Integer channelType = SeasonType.ONLINE_SELF_CHANNEL_TYPE.getCode();
        Result result = seasonFixedProductService.getFixedSeasonProductDetails(productId);
        if (result.isSuccess()) {
            //固定套票各种产品设置
            FixedSeasonDetailsDTO detailsDTO = (FixedSeasonDetailsDTO) result.getData();

            req.setChannelId(detailsDTO.getChargeUserId());
            LocalDate startDate = LocalDate.now();
            //添加各个单项的值
            LocalDate endDate = startDate.plusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
            List<DepartCalendarDTO> departCalendarDTOList = seasonFixedProductService.getDepartCalendarDTOList(productId, startDate, endDate, detailsDTO, SeasonType.OFFLINE_SELF_CHANNEL_TYPE.getCode(), req.getChannelId());
            detailsDTO.setDepartCalendarDTOList(departCalendarDTOList);
            if (null != departCalendarDTOList && departCalendarDTOList.size() > 0) {
                List<LocalDate> localDate = departCalendarDTOList.get(0).getValidDateList();
                BigDecimal fixedSeasonCostPrice = BigDecimal.ZERO;
                if (null != localDate && localDate.size() > 0) {
                    LocalDate departDate = localDate.get(0);
                    //获取固定套票 打包产品的 价格
                    getSinglePriceList(req.getTripType(), req.getProductFlag(), detailsDTO, departDate, detailsDTO.getTravelDays(), detailsDTO.getTravelNights(), SeasonType.OFFLINE_SELF_CHANNEL_TYPE.getCode(),req.getChannelId());
                }
                detailsDTO.setProductPrice(fixedSeasonCostPrice);
            }
            return Result.success(detailsDTO);
        } else {
            return result;
        }
    }

    public BigDecimal getFixedSeasonProductCosts(FixedSeasonDetailsDTO detailsDTO) {
        Integer minPeopleNumber = detailsDTO.getMinPeopleNumber();
        BigDecimal cost = BigDecimal.ZERO;
        List<SeasonFixedProductPackageAirDTO> seasonFixedProductPackageAirList = detailsDTO.getSeasonFixedProductPackageAirList();
        if (seasonFixedProductPackageAirList.size() > 0) {
            boolean departFlag = true;
            boolean returnFlag = true;
            BigDecimal itemCost = BigDecimal.ZERO;
            for (SeasonFixedProductPackageAirDTO item : seasonFixedProductPackageAirList) {
                if (SeasonType.YES_DEFAULT.getCode() == item.getIsDefault()) {
                    if (departFlag && SeasonType.JOURNEY_TYPE_DEPART.getKey().equals(item.getTripType())) {
                        itemCost = itemCost.add(item.getCost());
                        departFlag = false;
                    }
                    if (returnFlag && SeasonType.JOURNEY_TYPE_RETURN.getKey().equals(item.getTripType())) {
                        itemCost = itemCost.add(item.getCost());
                        returnFlag = false;
                    }
                }
            }
            cost = cost.add(itemCost.multiply(new BigDecimal(minPeopleNumber)));
        }
        List<SeasonFixedProductPackageBusDTO> seasonFixedProductPackageBusList = detailsDTO.getSeasonFixedProductPackageBusList();
        if (seasonFixedProductPackageBusList.size() > 0) {
            boolean departFlag = true;
            boolean returnFlag = true;
            BigDecimal itemCost = BigDecimal.ZERO;
            for (SeasonFixedProductPackageBusDTO item : seasonFixedProductPackageBusList) {
                if (SeasonType.YES_DEFAULT.getCode() == item.getIsDefault()) {
                    if (departFlag && SeasonType.JOURNEY_TYPE_DEPART.getKey().equals(item.getTripType())) {
                        itemCost = itemCost.add(item.getCost());
                        departFlag = false;
                    }
                    if (returnFlag && SeasonType.JOURNEY_TYPE_RETURN.getKey().equals(item.getTripType())) {
                        itemCost = itemCost.add(item.getCost());
                        returnFlag = false;
                    }
                }
            }
            cost = cost.add(itemCost.multiply(new BigDecimal(minPeopleNumber)));
        }
        List<SeasonFixedProductPackageShipDTO> seasonFixedProductPackageShipList = detailsDTO.getSeasonFixedProductPackageShipList();
        if (seasonFixedProductPackageShipList.size() > 0) {
            boolean departFlag = true;
            boolean returnFlag = true;
            BigDecimal itemCost = BigDecimal.ZERO;
            for (SeasonFixedProductPackageShipDTO item : seasonFixedProductPackageShipList) {
                if (SeasonType.YES_DEFAULT.getCode() == item.getIsDefault()) {
                    if (departFlag && SeasonType.JOURNEY_TYPE_DEPART.getKey().equals(item.getTripType())) {
                        itemCost = itemCost.add(item.getCost());
                        departFlag = false;
                    }
                    if (returnFlag && SeasonType.JOURNEY_TYPE_RETURN.getKey().equals(item.getTripType())) {
                        itemCost = itemCost.add(item.getCost());
                        returnFlag = false;
                    }
                }
            }
            cost = cost.add(itemCost.multiply(new BigDecimal(minPeopleNumber)));
        }
        List<SeasonFixedProductPackageTrainDTO> seasonFixedProductPackageTrainList = detailsDTO.getSeasonFixedProductPackageTrainList();
        if (seasonFixedProductPackageTrainList.size() > 0) {
            boolean departFlag = true;
            boolean returnFlag = true;
            BigDecimal itemCost = BigDecimal.ZERO;
            for (SeasonFixedProductPackageTrainDTO item : seasonFixedProductPackageTrainList) {
                if (SeasonType.YES_DEFAULT.getCode() == item.getIsDefault()) {
                    if (departFlag && SeasonType.JOURNEY_TYPE_DEPART.getKey().equals(item.getTripType())) {
                        itemCost = itemCost.add(item.getCost());
                        departFlag = false;
                    }
                    if (returnFlag && SeasonType.JOURNEY_TYPE_RETURN.getKey().equals(item.getTripType())) {
                        itemCost = itemCost.add(item.getCost());
                        returnFlag = false;
                    }
                }
            }
            cost = cost.add(itemCost.multiply(new BigDecimal(minPeopleNumber)));
        }

        List<SeasonFixedProductPackageHotelDTO> seasonFixedProductPackageHoteList = detailsDTO.getSeasonFixedProductPackageHoteList();
        if (seasonFixedProductPackageHoteList.size() > 0) {
            for (SeasonFixedProductPackageHotelDTO item : seasonFixedProductPackageHoteList) {
                if (SeasonType.YES_DEFAULT.getCode() == item.getIsDefault()) {
                    cost = cost.add(item.getCost());
                    break;
                }
            }
        }
        List<SeasonFixedProductPackageScenicDTO> seasonFixedProductPackageScenicList = detailsDTO.getSeasonFixedProductPackageScenicList();
        if (seasonFixedProductPackageScenicList.size() > 0) {
            for (SeasonFixedProductPackageScenicDTO item : seasonFixedProductPackageScenicList) {
                if (SeasonType.YES_DEFAULT.getCode() == item.getIsDefault()) {
                    cost = cost.add(item.getCost());
                    break;
                }
            }
        }
        List<SeasonFixedProductPackageLocalFunDTO> seasonFixedProductPackageLocalFunList = detailsDTO.getSeasonFixedProductPackageLocalFunList();
        if (seasonFixedProductPackageLocalFunList.size() > 0) {
            for (SeasonFixedProductPackageLocalFunDTO item : seasonFixedProductPackageLocalFunList) {
                if (SeasonType.YES_DEFAULT.getCode() == item.getIsDefault()) {
                    cost = cost.add(item.getCost());
                    break;
                }
            }
        }
        List<SeasonFixedProductPackageCommodityDTO> seasonFixedProductPackageCommodityList = detailsDTO.getSeasonFixedProductPackageCommodityList();
        if (seasonFixedProductPackageCommodityList.size() > 0) {
            for (SeasonFixedProductPackageCommodityDTO item : seasonFixedProductPackageCommodityList) {
                if (SeasonType.YES_DEFAULT.getCode() == item.getIsDefault()) {
                    cost = cost.add(item.getCost());
                    break;
                }
            }
        }
        return cost;
    }


    /* @MethodName:根据用户id  出发日期  结束日期 获取该 时间段内是否有 加幅信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/23 15:02
     **/
    @Override
    public List<StrategyInfoDateDTO> getOptionalCalendar(SeasonProductStrategyQueryByDateReq req, TokenUser user, Integer channelType) {
        return seasonProductStrategyService.getOptionalCalendar(req, user, channelType);
    }

    //增加足迹
    private void addUserFootPoint(FixedSeasonDetailsDTO details, Long detailId, Long userId) {
        try {
            if (userId != null) {
                UserFootPointReq req = new UserFootPointReq();
                req.setUserId(userId);
                req.setType(SystemBusinessType.FIXED_PACKAGE_TICKET.getCode());
                req.setTitle(details.getProductName());
                req.setContent(details.getSubtitle());
                req.setCurrencyId(Currency.HKD.getCode());
                req.setCurrency(Currency.HKD.getCurrency());
                req.setPrice(details.getProductPrice());
                req.setCoverUrl(details.getIntroducePicture());
                req.setDetailId(detailId);
                userFootPointService.add(req);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
